package com.apes.hr.group.service;

import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.hr.base.model.Employee;
import com.apes.hr.base.model.WorkPost;
import com.apes.hr.base.repository.WorkPostRepository;
import com.apes.hr.group.model.DingDingDeptRelevance;
import com.apes.hr.group.repository.DingDingDeptRelevanceRepository;
import com.apes.hr.group.repository.DingDingDeptRepository;
import com.apes.hr.thirdParty.dingidng.model.DingDingToken;
import com.apes.hr.thirdParty.dingidng.service.DingDingService;
import com.apes.hr.transfer.service.TransferApplicationItemService;
import com.apes.scm.masterdata.frame.model.Branch;
import com.apes.scm.masterdata.frame.repository.BranchEntryRepository;
import com.apes.scm.masterdata.frame.repository.BranchRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;

import com.dingtalk.api.request.OapiUserUpdateRequest;
import com.dingtalk.api.response.OapiUserDeleteResponse;
import com.dingtalk.api.response.OapiUserUpdateResponse;
import com.taobao.api.ApiException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 功能：部门群组关联公司部门岗位表
 * @author ZhengZX
 * @create 2020年9月15日11:30:25
 */
@Service("hrDingDingDeptRelevanceService")
public class DingDingDeptRelevanceService extends DomainService {

    @Autowired
    private WorkPostRepository workPostRepository;
    @Autowired
    private BranchRepository branchRepository;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private DingDingDeptRelevanceRepository dingDingDeptRelevanceRepository;
    @Autowired
    private DingDingDeptService dingDingDeptService;
    @Autowired
    private DingDingService dingService;
    @Autowired
    private DingDingToken dingDingToken;
    @Autowired
    public TransferApplicationItemService itemService;
    @Autowired
    public BranchEntryRepository branchEntryRepository;
    @Autowired
    public DingDingDeptRepository dingDingDeptRepository;

    public DingDingDeptRelevance save(SimpleRequest request){
        DingDingDeptRelevance deptRelevance = request.getO(DingDingDeptRelevance.class);
        DingDingDeptRelevance dingDingDept = dingDingDeptRelevanceRepository.findByDingDingDept(deptRelevance.getDingDingDept());
        if (dingDingDept != null) throw new
                RuntimeException("[ "+dingDingDept.getDingDingDept().getId()+" ]" + dingDingDept.getDingDingDept().getName() + "已存在对应维护关系");
        deptRelevance.getDingDingDept().getId();
        maintain(deptRelevance);//维护中间表信息
        deptRelevance.setId(SpringManager.getBean(SequenceService.class).getId(DingDingDeptRelevance.CONST_TABLE_NAME));
        DingDingDeptRelevance result = dingDingDeptRelevanceRepository.saveAndFlush(deptRelevance);
        //设置前端下拉框界面转化
        result.setWorkPostList(deptRelevance.getWorkPostList());
        result.setBranchList(deptRelevance.getBranchList());
        result.setCompanyList(deptRelevance.getCompanyList());
        return result;
    }

    /*
     * 定义钉钉部门群 数据格式化给前端
     * */
    public Page<DingDingDeptRelevance> findAllForUi(SimpleRequest request) {
        Page<DingDingDeptRelevance> deptRelevancePage = request.getO(Page.class);
        deptRelevancePage.getContent().stream().forEach(
                (d) -> {
                    List<WorkPost> workPosts = d.getWorkPosts();
                    List<PartyRole> partyRoles = d.getPartyRoles();
                    List<Branch> branches = d.getBranches();
                    if (workPosts != null) {
                        List workPostList = new ArrayList();
                        workPosts.stream().forEach(
                                (workPost) -> {
                                    JSONObject workPostJo = new JSONObject();
                                    workPostJo.put("id", workPost.getId());
                                    workPostJo.put("name", workPost.getName());
                                    workPostList.add(workPostJo);
                                }
                        );
                        d.setWorkPostList(workPostList);
                    }
                    if (partyRoles != null) {
                        List partyRoleList = new ArrayList();
                        partyRoles.stream().forEach(
                                (partyRole) -> {
                                    JSONObject partyRoleJo = new JSONObject();
                                    partyRoleJo.put("id", partyRole.getId());
                                    partyRoleJo.put("name", partyRole.getName());
                                    partyRoleList.add(partyRoleJo);
                                }
                        );
                        d.setCompanyList(partyRoleList);
                    }
                    if (branches != null) {
                        List branchList = new ArrayList();
                        branches.stream().forEach(
                                (branch) -> {
                                    JSONObject branchJo = new JSONObject();
                                    branchJo.put("id", branch.getId());
                                    branchJo.put("name", branch.getName());
                                    branchList.add(branchJo);
                                }
                        );
                        d.setBranchList(branchList);
                    }
                }
        );
        return deptRelevancePage;
    }

    //删除
    public String delete(SimpleRequest request){
        String id = request.get("id");
        long versions = (int) request.get("version"); // 获取当前请求的版本信息
        DingDingDeptRelevance deptRelevance = dingDingDeptRelevanceRepository.findOne(id);
        if (deptRelevance == null) throw new RuntimeException("钉钉部门【" + id + "】在系统中不存在。");
        if (deptRelevance.getVersion() != versions) throw new RuntimeException("记录已更新或已删除，请重新提交！");  // 用于判断当前版本是否被修改
        dingDingDeptRelevanceRepository.delete(deptRelevance);
        return "删除成功！";
    }

    //修改
    public DingDingDeptRelevance update(SimpleRequest request) {
        String id = request.get("id");
        long versions = (int) request.get("version"); // 获取当前请求的版本信息
        DingDingDeptRelevance tempDeptRelevance = dingDingDeptRelevanceRepository.findOne(id);  //数据库信息
        DingDingDeptRelevance deptRelevance = request.getO(DingDingDeptRelevance.class);        //前端
//        if(tempDeptRelevance.getId().equals(deptRelevance.getId()))
//            throw new RuntimeException("[ "+deptRelevance.getDingDingDept().getId()+" ]" + deptRelevance.getDingDingDept().getName() + "已存在对应维护关系");
        if (tempDeptRelevance == null) throw new RuntimeException("钉钉部门【" + id + "】在系统中不存在。");
        if (tempDeptRelevance.getVersion() != versions) throw new RuntimeException("记录已更新或已删除，请重新提交！");  // 用于判断当前版本是否被修改
        maintain(deptRelevance);//维护中间表信息
        DingDingDeptRelevance result = dingDingDeptRelevanceRepository.saveAndFlush(deptRelevance);
        //设置前端下拉框界面转化
        result.setWorkPostList(deptRelevance.getWorkPostList());
        result.setBranchList(deptRelevance.getBranchList());
        result.setCompanyList(deptRelevance.getCompanyList());
        return result;
    }

    /**
     * 维护中间表信息（公司，行政部门，岗位）
     * @param deptRelevance
     */
    public void maintain(DingDingDeptRelevance deptRelevance){
        //添加岗位中间表信息
        List<JSONObject> workPostList = deptRelevance.getWorkPostList();
        if (workPostList != null) {
            List<WorkPost> workPosts = new ArrayList<>();
            workPostList.stream().forEach(
                    (workPostJ) -> {
                        WorkPost workPost = workPostRepository.findOne(workPostJ.getString("id"));
                        workPosts.add(workPost);
                    }
            );
            deptRelevance.setWorkPosts(workPosts);
        }
        //添加公司中间表信息
        List<JSONObject> companyList = deptRelevance.getCompanyList();
        if (companyList != null) {
            List<PartyRole> partyRoles = new ArrayList<>();
            companyList.stream().forEach(
                    (companyJ) -> {
                        PartyRole partyRole = partyRoleRepository.findOne(companyJ.getString("id"));
                        partyRoles.add(partyRole);
                    }
            );
            deptRelevance.setPartyRoles(partyRoles);
        }
        //添加部门中间表信息
        List<JSONObject> branchList = deptRelevance.getBranchList();
        if (branchList != null) {
            List<Branch> branches = new ArrayList<>();
            branchList.stream().forEach(
                    (branchJ) -> {
                        Branch branch = branchRepository.findOne(branchJ.getString("id"));
                        branches.add(branch);
                    }
            );
            deptRelevance.setBranches(branches);
        }
    }

    /**
     * 根据公司部门岗位三个维度查找对应相关的钉钉群ID
     * @param company
     * @param branch
     * @param workPost
     * @return departments 所有的钉钉群号
     */
    public List<Long> transferDingDing(PartyRole company, Branch branch ,WorkPost workPost){
        List<Long> departments = new ArrayList();   //存放钉钉群编号

        List<DingDingDeptRelevance> dingDeptRelevances = dingDingDeptRelevanceRepository.findAll(   //公司+部门+岗位三个维度都为空默认查所有（全员群）
                JpaDsl.toCriteria(
                        "partyRoles.id","EQ", null,
                        "branches.id","EQ", null,
                        "workPosts.id","EQ", null
                )
        );
        List<DingDingDeptRelevance> dingDeptRelevances1 = dingDingDeptRelevanceRepository.findAll(   //查询满足公司+部门+岗位三个维度的群
                JpaDsl.toCriteria(
                        "partyRoles.id","EQ", company.getId(),
                        "branches.id","EQ", branch.getId(),
                        "workPosts.id","EQ", workPost.getId()
                )
        );
        List<DingDingDeptRelevance> dingDeptRelevances2 = dingDingDeptRelevanceRepository.findAll(   //查询满足公司+部门维度的群
                JpaDsl.toCriteria(
                        "partyRoles.id","EQ", company.getId(),
                        "branches.id","EQ", branch.getId(),
                        "workPosts.id","EQ", null
                )
        );
        List<DingDingDeptRelevance> dingDeptRelevances3 = dingDingDeptRelevanceRepository.findAll(   //查询满足公司+岗位维度的群
                JpaDsl.toCriteria(
                        "partyRoles.id","EQ", company.getId(),
                        "branches.id","EQ", null,
                        "workPosts.id","EQ", workPost.getId()
                )
        );
        List<DingDingDeptRelevance> dingDeptRelevances4 = dingDingDeptRelevanceRepository.findAll(   //查询满足部门+岗位维度的群
                JpaDsl.toCriteria(
                        "partyRoles.id","EQ", null,
                        "branches.id","EQ", branch.getId(),
                        "workPosts.id","EQ", workPost.getId()
                )
        );
        List<DingDingDeptRelevance> dingDeptRelevances5 = dingDingDeptRelevanceRepository.findAll(   //查询只满足公司维度的群
                JpaDsl.toCriteria(
                        "partyRoles.id","EQ", company.getId(),
                        "branches.id","EQ", null,
                        "workPosts.id","EQ", null
                )
        );
        List<DingDingDeptRelevance> dingDeptRelevances6 = dingDingDeptRelevanceRepository.findAll(   //查询只满足部门维度的群
                JpaDsl.toCriteria(
                        "partyRoles.id","EQ", null,
                        "branches.id","EQ", branch.getId(),
                        "workPosts.id","EQ", null
                )
        );
        List<DingDingDeptRelevance> dingDeptRelevances7 = dingDingDeptRelevanceRepository.findAll(   //查询只满足岗位维度的群
                JpaDsl.toCriteria(
                        "partyRoles.id","EQ", null,
                        "branches.id","EQ", null,
                        "workPosts.id","EQ", workPost.getId()
                )
        );

        //添加群ID
//        dingDeptRelevances.addAll()
        dingDeptRelevances.stream().forEach(d -> departments.add(Long.valueOf(d.getDingDingDept().getId())));
        dingDeptRelevances1.stream().forEach(d -> departments.add(Long.valueOf(d.getDingDingDept().getId())));
        dingDeptRelevances2.stream().forEach(d -> departments.add(Long.valueOf(d.getDingDingDept().getId())));
        dingDeptRelevances3.stream().forEach(d -> departments.add(Long.valueOf(d.getDingDingDept().getId())));
        dingDeptRelevances4.stream().forEach(d -> departments.add(Long.valueOf(d.getDingDingDept().getId())));
        dingDeptRelevances5.stream().forEach(d -> departments.add(Long.valueOf(d.getDingDingDept().getId())));
        dingDeptRelevances6.stream().forEach(d -> departments.add(Long.valueOf(d.getDingDingDept().getId())));
        dingDeptRelevances7.stream().forEach(d -> departments.add(Long.valueOf(d.getDingDingDept().getId())));

        return departments;
    }

    /**
     * 获取部门群
     * @param branch
     * @return
     */
    public List<Long> getBranchDingDing(Branch branch){
        List<Long> departments = new ArrayList<>();
        List<DingDingDeptRelevance> dingDeptRelevances = dingDingDeptRelevanceRepository.findAll(   //查询只满足部门维度的群
                JpaDsl.toCriteria(
                        "partyRoles.id","EQ", null,
                        "branches.id","EQ", branch.getId(),
                        "workPosts.id","EQ", null
                )
        );
        dingDeptRelevances.stream().forEach(d -> departments.add(Long.valueOf(d.getDingDingDept().getId())));
        return departments;
    }

//    @OutboxSubscriber(name = "开店申请创建钉钉群")
//    public void branchEntryTime(BranchEntry branchEntry) {
//        if (branchEntry.isAutoFound()){ //选择了自动建群
//            dingDingDeptService.passBranchSaveDept(branchEntry);    //通过开店的部门名称创建一个钉钉群
//        }
//    }

//    @OutboxSubscriber(name = "执行离职操作")
//    public void calcutelateTime(QuitJobOrder quitJobOrder) {
//        if (!quitJobOrder.getState().equals("confirm")) return;
        //离职删除钉钉用户
//        deleteDingDingUser(quitJobOrder.getEmployee());
//    }

//    @OutboxSubscriber(name = "员工入职确认报道")
//    public void doneTime(ApplyJobOrder applyJobOrder) {
//        if (!applyJobOrder.getState().equals("done")) return;
//        //入职成功后 获取对应的钉钉群ID
//        List<Long> list = transferDingDing(applyJobOrder.getCompany(), applyJobOrder.getBranch(), applyJobOrder.getWorkPost());
//        //入职人员的钉钉ID
//        String dingDingUserId = applyJobOrder.getEmployee().getParty().getPerson().getDingDingUserId();
//        //更新用户到对应的钉钉群
//        dingDingDeptService.userUpdate(list,dingDingUserId);
//        //如果入职的员工岗位是店长设置为入职部门群的主管
//        if (applyJobOrder.getWorkPost().getId().equals("0000016")&&applyJobOrder.getWorkPost().getName().equals("店长")){
//            List<Long> branchDingDing = getBranchDingDing(applyJobOrder.getBranch());   //根据部门获取对应的钉钉群
//            for (Long b : branchDingDing) {
//                String zgByDept = dingDingDeptService.getZGByDept(String.valueOf(b));
//                if (zgByDept!=null){
//                    //前面有主管id进行格式拼接
//                    zgByDept = zgByDept + "|";
//                }
//                zgByDept = zgByDept + dingDingUserId;
//                //执行更新部门主管操作
//                dingDingDeptService.updateDeptByZG(b,zgByDept);
//            }
//        }
//    }

    //调动申请单
//    @OutboxSubscriber(id = "local:hrDingDingDeptRelevanceService.transferTime", name = "调动申请单")
//    public void transferTime(OutboxPayloadWrapper outboxPayloadWrapper) {
//        JSONObject object = JSONObject.parseObject(outboxPayloadWrapper.getPayload());
//        List<TransferApplicationItem> item = itemService.findById(object.getInteger("id"));
//        item.stream().forEach(itemzz -> {
//            //同步钉钉群组
//            List<Long> departments = transferDingDing
//                    (itemzz.getTransferUid().getCompany(), itemzz.getBranchAfter(), itemzz.getWorkPostAfter());
//            String userDingDingId = itemzz.getTransferUid().getParty().getPerson().getDingDingUserId();
//            List<Long> oldDepartments = dingDingDeptService.getUser(userDingDingId);
//
//            String sType = itemzz.getTransferApplications().getHrTransferType().getId();
//
//            if (sType.equals("000102")){
//                //调动单 更新到新的钉钉群组
//                dingDingDeptService.userUpdate(departments,userDingDingId);
//                updateDingDingUser(itemzz.getTransferUid(),userDingDingId);
//            }else if (sType.equals("000103")){
//                //支援单 更新到新的钉钉群组
//                //原来的钉钉群和支援后的钉钉群组合
//                List<Long> newDepartments = Stream.of(departments, oldDepartments)
//                        .flatMap(Collection::stream)
//                        .distinct()
//                        .collect(Collectors.toList());
//                dingDingDeptService.userUpdate(newDepartments,userDingDingId);
//            }
//        });
//    }

//    @OutboxSubscriber(id = "local:hrDingDingDeptRelevanceService.zzRYXXTime", name = "终止申请单")
//    public void zzRYXXTime(OutboxPayloadWrapper outboxPayloadWrapper) {
//        JSONObject object = JSONObject.parseObject(outboxPayloadWrapper.getPayload());
//        List<TransferApplicationItem> item = itemService.findById(object.getInteger("id"));
//        item.stream().forEach(itemzz ->{
//            String userDingDingId = itemzz.getTransferUid().getParty().getPerson().getDingDingUserId();
//            if(item.get(0).getTransferApplications().getHrTransferType().getDescription().equals("调动")){
//                updateDingDingUser(itemzz.getTransferUid(),userDingDingId);
//            }
//            // 同步钉钉部门使用
//            //根据调动前公司部门岗位找符合的群
//            List<Long> departments = transferDingDing
//                    (itemzz.getTransferUid().getCompany(), itemzz.getBranch(), itemzz.getWorkPost());
//
//            //更新到对应的群
//            dingDingDeptService.userUpdate(departments,userDingDingId);
//        });

//    }


    /**
     * 删除钉钉用户
     * @param employee
     * @return
     * @throws
     */
    public String deleteDingDingUser(Employee employee){

        //获取 accessToken
        String accessToken = dingDingToken.getToken();
        String userId = employee.getParty().getPerson().getDingDingUserId();
        if (userId==null)throw new RuntimeException("系统里没有对应的钉钉ID.不能删除!");
        OapiUserDeleteResponse response = dingService.deleteUser(accessToken,userId);
        if (response.getErrcode()!=0){
            throw new RuntimeException("删除钉钉用户失败!"+  response.getErrmsg());
        }
        return response.getErrmsg();
    }

    /**
     * 更新钉钉用户信息
     * @param employee 员工资料
     */
    public void updateDingDingUser(Employee employee,String userDingDingId) {
        OapiUserUpdateRequest request = new OapiUserUpdateRequest();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        //获取 accessToken
        String accessToken = dingDingToken.getToken();
        request.setUserid(userDingDingId);
        String name = employee.getName();
        String mobile = employee.getMobileNumber();
        String jobName = employee.getJob().getName();//职位
        Date entryDate = employee.getEntryDate();//入职时间
        Date birthday = employee.getBirthday();//生日
        String origin = employee.getOrigin();//工号
//        String degree = applyJobOrder.getDegree().getDescription();//学历

        request.setName(name);
        request.setMobile(mobile);
        request.setPosition(jobName);
        request.setJobnumber(origin);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("生日",formatter.format(birthday));
//        jsonObject.put("学历",degree);
        jsonObject.put("hiredDate",entryDate.getTime());
        request.setExtattr(jsonObject.toJSONString());
        OapiUserUpdateResponse response = dingService.updateUser(request,accessToken);
        if (response.getErrcode()!=0){
            throw new RuntimeException("同步钉钉用户失败!" + response.getErrmsg());
        }
    }


}
